package com.jagochan.module.rbac.sys_menu.controller;

import com.jagochan.common.result.ResultUtils;
import com.jagochan.common.result.ResultVo;
import com.jagochan.module.rbac.common.Constants;
import com.jagochan.module.rbac.sys_menu.domain.SysMenu;
import com.jagochan.module.rbac.sys_menu.domain.vo.MenuTreeAssignVo;
import com.jagochan.module.rbac.sys_menu.domain.vo.TreeVueRouterVO;
import com.jagochan.module.rbac.sys_menu.service.SysMenuService;
import com.jagochan.module.rbac.sys_user.domain.SysUser;
import com.jagochan.module.rbac.sys_user.service.SysUserService;
import lombok.RequiredArgsConstructor;
import org.apache.commons.lang.StringUtils;
import org.springframework.web.bind.annotation.*;

import java.util.*;
import java.util.stream.Collectors;

@RequiredArgsConstructor
@RequestMapping("/api/menu")
@RestController
public class SysMenuController {

    private final SysMenuService sysMenuService;
    private final SysUserService sysUserService;

    @PostMapping
    public ResultVo<?> add(@RequestBody SysMenu sysMenu) {
        Date now = new Date();
        sysMenu.setCreateTime(now);
        sysMenu.setUpdateTime(now);
        sysMenu.setMenuId(null);
        if (sysMenuService.save(sysMenu)) {
            return ResultUtils.success("新增菜单成功!");
        }
        return ResultUtils.error("新增菜单失败!");
    }

    @PutMapping
    public ResultVo<?> edit(@RequestBody SysMenu sysMenu) {
        sysMenu.setUpdateTime(new Date());
        if (sysMenuService.updateById(sysMenu)) {
            return ResultUtils.success("编辑菜单成功!");
        }
        return ResultUtils.error("编辑菜单失败!");
    }

    @DeleteMapping("/{menuId}")
    public ResultVo<?> delete(@PathVariable("menuId") Long menuId) {
        // 判断是否有子菜单
        Long count = sysMenuService.lambdaQuery().eq(SysMenu::getParentId, menuId).count();
        if (count > 0) {
            return ResultUtils.error("存在" + count + "个子菜单，不能删除!");
        }

        if (sysMenuService.removeById(menuId)) {
            return ResultUtils.success("删除菜单成功!");
        }
        return ResultUtils.error("删除菜单失败!");
    }

    @GetMapping("/list-menu-tree")
    public ResultVo<List<SysMenu>> listMenuTree() {
        return ResultUtils.success("查询菜单树成功", sysMenuService.listMenuTree());
    }

    @GetMapping("/list-parent-menu-tree")
    public ResultVo<List<SysMenu>> listParentMenuTree() {
        return ResultUtils.success("查询父级菜单树成功", sysMenuService.listParentMenuTree());
    }

    @GetMapping("/list-tree-menu/{userId}/{roleId}")
    public ResultVo<MenuTreeAssignVo> listTreeMenuByRoleAndUser(@PathVariable String roleId, @PathVariable String userId) {
        return ResultUtils.success("查询成功", sysMenuService.listTreeMenuByRoleAndUser(roleId, userId));
    }

    /**
     * 查询当前用户拥有的【菜单】，把菜单组装为vue-router格式（用于后台管理系统左侧的菜单导航）
     */
    @GetMapping("/list-vue-router-tree")
    public ResultVo<List<TreeVueRouterVO>> listVueRouterTree(String userId) {
        // 根据用户ID查询用户
        SysUser user = sysUserService.getById(userId);
        if (Objects.isNull(user)) return ResultUtils.error("用户不存在👉userId = " + userId, null);

        List<SysMenu> menuList;
        String isAdmin = user.getIsAdmin();
        if (StringUtils.isNotEmpty(isAdmin) && Constants.IS_ADMIN.equals(isAdmin)) { //  是超级管理员
            menuList = sysMenuService.lambdaQuery().orderByAsc(SysMenu::getOrderNum).list();
        } else { // 是普通用户
            menuList = sysMenuService.listMenuByUserId(userId);
        }

        if (menuList == null || menuList.isEmpty()) {
            return ResultUtils.success("无任何权限", Collections.emptyList());
        }
        // 过滤掉【按钮】类型菜单的
        menuList = menuList.stream()
                .filter(item -> item != null && StringUtils.isNotEmpty(item.getType()) && !item.getType().equals(Constants.BUTTON))
                .collect(Collectors.toList());
        // 把权限列表组装为vue-router（List<TreeVueRouterVO>）
        List<TreeVueRouterVO> vo = buildTreeVueRouterVOList(menuList, 0L);
        return ResultUtils.success("查询成功", vo);
    }

    private List<TreeVueRouterVO> buildTreeVueRouterVOList(List<SysMenu> menuList, Long parentMenuId) {
        return menuList.stream()
                .filter(item -> item != null && item.getParentId().equals(parentMenuId))
                .map(item -> {
                    TreeVueRouterVO.Meta meta = TreeVueRouterVO.Meta.builder()
                            .title(item.getTitle())
                            .icon(item.getIcon())
                            .roles(Arrays.asList(item.getCode().split(","))).build();
                    TreeVueRouterVO vo = TreeVueRouterVO.builder()
                            .path(item.getPath())
                            .component(item.getParentId() == 0L ? "TheLayout" : item.getUrl())
                            .name(item.getName())
                            .meta(meta)
                            .build();
                    if (Constants.MENU.equals(item.getType()) && item.getParentId() == 0L) { // 是菜单类型
                        vo.setRedirect(item.getPath());
                        vo.setPath(item.getPath() + "parent");
                        vo.setName(item.getName() + "parent");
                        vo.setChildren(List.of(TreeVueRouterVO.builder()
                                .name(item.getName()).path(item.getPath())
                                .component(item.getUrl())
                                .meta(meta.clone())
                                .build()));
                    } else {
                        vo.setChildren(buildTreeVueRouterVOList(menuList, item.getMenuId()));
                    }
                    return vo;
                }).collect(Collectors.toList());
    }

/*
    // 老师写的
    public List<TreeVueRouterVO> makeVueRouter(List<SysMenu> menuList, Long pid) {
        List<TreeVueRouterVO> list = new ArrayList<>();
        Optional.ofNullable(menuList).orElse(new ArrayList<>())
                .stream()
                .filter(item -> item != null && item.getParentId().equals(pid))
                .forEach(item -> {
                    TreeVueRouterVO router = new TreeVueRouterVO();
                    router.setName(item.getName());
                    router.setPath(item.getPath());
                    // 设置children 递归调用：自己调用自己
                    List<TreeVueRouterVO> children = makeVueRouter(menuList, item.getMenuId());
                    router.setChildren(children);
                    if (item.getParentId() == 0L) { // 如果是上级是0,那么他的component是Layout
                        router.setComponent("TheLayout");
                        // 判断该数据是目录还是菜单
                        if (item.getType().equals("1")) { // 如果一级菜单是 菜单类型，单独处理
                            router.setRedirect(item.getPath());
                            // 菜单需要设置children
                            List<TreeVueRouterVO> listChild = new ArrayList<>();
                            TreeVueRouterVO child = new TreeVueRouterVO();
                            child.setName(item.getName());
                            child.setPath(item.getPath());
                            child.setComponent(item.getUrl());
                            TreeVueRouterVO.Meta meta = TreeVueRouterVO.Meta.builder().title(item.getTitle())
                                    .icon(item.getIcon())
                                    .roles(Arrays.asList(item.getCode().split(",")))
                                    .build();
                            child.setMeta(meta);
                            listChild.add(child);
                            router.setChildren(listChild);
                            router.setPath(item.getPath() + "parent");
                            router.setName(item.getName() + "parent");
                        }
                    } else {
                        router.setComponent(item.getUrl());
                    }
                    TreeVueRouterVO.Meta meta1 = TreeVueRouterVO.Meta.builder().title(item.getTitle())
                            .icon(item.getIcon())
                            .roles(Arrays.asList(item.getCode().split(",")))
                            .build();
                    router.setMeta(meta1);
                    list.add(router);
                });
        return list;
    }
*/

}